#include <windows.h>
#include <gdiplus.h>
#pragma comment (lib, "Gdiplus.lib")

#include "drawer.h"


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
   Gdiplus::GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR           gdiplusToken;
   Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
   
   WNDCLASS wndClass;
   wndClass.style          = CS_HREDRAW | CS_VREDRAW;
   wndClass.lpfnWndProc    = WndProc;
   wndClass.cbClsExtra     = 0;
   wndClass.cbWndExtra     = 0;
   wndClass.hInstance      = hInstance;
   wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
   wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
   wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wndClass.lpszMenuName   = NULL;
   wndClass.lpszClassName  = TEXT("Geometry visualization");
   
   RegisterClass(&wndClass);

   HWND hWnd = CreateWindow(TEXT("Geometry visualization"), TEXT("Geometry"), 
   WS_OVERLAPPEDWINDOW | WS_VISIBLE, 50, 50, 450, 450, NULL, NULL, 
   hInstance, NULL);
     
   ShowWindow(hWnd, iCmdShow);
   UpdateWindow(hWnd);

   MSG msg;
   while(GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   
   Gdiplus::GdiplusShutdown(gdiplusToken);
   return msg.wParam;
} 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   static drawer_t drawer;
   static Gdiplus::Graphics * graphics = 0;

   switch(message)
   {
   case WM_PAINT:
	   {
		    if(graphics == 0)
			{
				PAINTSTRUCT  ps;
				HDC hdc = BeginPaint(hWnd, &ps);
				graphics = new Gdiplus::Graphics(hdc);
				drawer = drawer_t(graphics);
				drawer.paint();
			}
			return 0;
	   }
	case WM_KEYDOWN:
		{
			switch(wParam)
			{
			case VK_OEM_MINUS:
				drawer.decrease();
				break;
			case VK_OEM_PLUS:
				drawer.increase();
				break;
			case VK_LEFT:
				drawer.move(LEFT_M);
				break;
			case VK_RIGHT:
				drawer.move(RIGHT_M);
				break;
			case VK_UP:
				drawer.move(TOP_M);
				break;
			case VK_DOWN:
				drawer.move(BOTTOM_M);
				break;
			}
			return 0;
		}
   case WM_DESTROY:
		delete graphics;
		PostQuitMessage(0);
		return 0;
   default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
}
